﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AudiPyme.DAL
{
    public static class TiposAmenazasFactory
    {
        //Método que inserta un tipo de amenaza en la base de conocimiento
        public static void InsertarTipoAmenaza(TiposAmenazas t)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToTiposAmenazasEstablecer(t);
            agenteBD.SaveChanges();
        }

        //Método que indica si existe algún tipo de amenaza asociado al nombre contenido en NTipoAmenaza
        public static bool EstaTipoAmenaza(String NTipoAmenaza)
        {
            bool esta = false;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> TipoAmenazaIgual = from TipoAmenaza in agenteBD.TiposAmenazasEstablecer
                                                  select TipoAmenaza.TipoAmenaza;
            foreach (String v in TipoAmenazaIgual)
            {
                if (NTipoAmenaza.Equals(v.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    esta = true;
                }
            }
            return esta;
        }

        //Método que recoge los Tipos de Amenazas que están actualmente disponibles en la Base de Conocimiento
        public static IQueryable<TiposAmenazas> RecogeTiposAmenazas()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<TiposAmenazas> TipAmenaz = from TipAmen in agenteBD.TiposAmenazasEstablecer
                                                  where TipAmen.Actual == true
                                                  select TipAmen;
            if (TipAmenaz.Count() == 0)
            {
                return null;
            }
            return TipAmenaz;
        }

        //Método que actualiza los valores de un tipo de amenaza en la base de conocimiento
        public static void ActualizaTipoAmenaza(int IdTipoAmenaza, String Amenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var ActivoEmpresa = (from ActEmp in agenteBD.TiposAmenazasEstablecer
                                 where ActEmp.IdTipoAmenaza == IdTipoAmenaza
                                 select ActEmp).Single();
            ActivoEmpresa.TipoAmenaza = Amenaza;
            agenteBD.SaveChanges();
        }

        //Método que hace un borrado lógico de un Tipo Amenaza asi como de todos los elementos de las Tablas depedientes de él en la BD
        public static void EliminaTipoAmenaza(int IdTipoAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            TiposAmenazas TipAmenElim = (from TipAmen in agenteBD.TiposAmenazasEstablecer
                                         where TipAmen.IdTipoAmenaza == IdTipoAmenaza
                                         select TipAmen).Single();
            TipAmenElim.Actual = false;
            agenteBD.SaveChanges();
            //Estructuras para recoger los elementos a eliminar
            //Lista de Amenazas por Tipo de Amenaza
            List<Amenazas> LAmenazasTipAmenaza = new List<Amenazas>();
            //Lista de Relaciones Tipo Activo - Amenaza - Criterio de Riesgo por Amenazas
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorAmenaza = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            List<Matriz_Amenazas_Controles> LRelAmenControlPorAmenaza = new List<Matriz_Amenazas_Controles>();
            List<Matriz_AmenazasVulnerabilidades> LRelAmenVulnPorAmenaza = new List<Matriz_AmenazasVulnerabilidades>();
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstPorRelTipActAmenCrit = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            //Recorremos todas las tablas de primer nivel de dependencia con el TipoAmenaza eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Amenazas
            LAmenazasTipAmenaza = AmenazasFactory.EliminaAmenazasPorTipoAmenaza(IdTipoAmenaza);
            //Nivel 2 de Dependencia
            if (LAmenazasTipAmenaza.Count != 0)
            {
                //Matriz_TipoActivosAmenazasCriterioRiesgo
                LRelTipActAmenCritPorAmenaza = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.EliminaRelacionesPorAmenaza(LAmenazasTipAmenaza);
                //Matriz_Amenazas_Controles
                LRelAmenControlPorAmenaza = Matriz_Amenazas_ControlesFactory.EliminaRelacionesPorAmenaza(LAmenazasTipAmenaza);
                //Matriz Amenazas_Vulnerabilidades
                LRelAmenVulnPorAmenaza = Matriz_AmenazasVulnerabilidadesFactory.EliminaRelacionesPorAmenaza(LAmenazasTipAmenaza);
            }
            //Nivel 3 de Dependencia
            if (LRelTipActAmenCritPorAmenaza.Count() != 0)
            {
                //Instancias Tipo Activo - Amenaza - Criterio de Riesgo
                LInstPorRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.EliminaInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorAmenaza);
            }

        }

        //Método que devuelve el nombre de los Tipo de Amenaza actuales ordenados a través de su Id
        public static List<String> NombresTipoAmenaza()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<String> LNombresTipoAmenaza = new List<String>();
            IQueryable<String> NombreTipAmen = (from TipAmen in agenteBD.TiposAmenazasEstablecer
                                                where TipAmen.Actual == true
                                                orderby TipAmen.IdTipoAmenaza
                                                select TipAmen.TipoAmenaza);
            if (NombreTipAmen.Count() != 0)
            {
                foreach (String TA in NombreTipAmen)
                {
                    LNombresTipoAmenaza.Add(TA);
                }
            }
            return LNombresTipoAmenaza;
        }

        //Método que devuelve el Id de un Tipo de Amenaza por su nombre
        public static int IdTipoAmenaza(String TipoAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int IdTipoAmenaza = 0;
            IQueryable<int> IdTipAmen = from TipAmen in agenteBD.TiposAmenazasEstablecer
                                        where TipAmen.TipoAmenaza.Equals(TipoAmenaza)
                                        select TipAmen.IdTipoAmenaza;
            if (IdTipAmen.Count() != 0)
            {
                IdTipoAmenaza = IdTipAmen.First();
            }
            return IdTipoAmenaza;
        }

        //Devuelve el tipo de amenaza de una amenaza dada
        public static int IdTipoAmenaza(int IdAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int IdTipoAmenaza = 0;
            IQueryable<int> IdTipAmen = from Amen in agenteBD.AmenazasEstablecer
                                        where Amen.IdAmenaza == IdAmenaza
                                        select Amen.IdTipoAmenaza;
            if (IdTipAmen.Count() != 0)
            {
                IdTipoAmenaza = IdTipAmen.First();
            }
            return IdTipoAmenaza;
        }

        //Método que devuelve el Nombre de un Tipo de Amenaza relacionado con un IdTipoAmenaza de una Amenaza
        public static string NombreTipoAmenaza(int IdAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NombreTipAmen = (from Amen in agenteBD.AmenazasEstablecer
                                                join TipAmen in agenteBD.TiposAmenazasEstablecer on Amen.IdTipoAmenaza equals TipAmen.IdTipoAmenaza
                                                where Amen.IdAmenaza == IdAmenaza && Amen.IdTipoAmenaza == TipAmen.IdTipoAmenaza
                                                select TipAmen.TipoAmenaza);
            if (NombreTipAmen.Count() == 0)
            {
                return "";
            }
            return NombreTipAmen.First();
        }

        //Devuelve el nombre del identificador de un tipo de amenaza
        public static string NombreTipoAmenazaPorId(int IdTipoAmenaza)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NombreTipAmen = (from TipAmen in agenteBD.TiposAmenazasEstablecer
                                                where TipAmen.IdTipoAmenaza == IdTipoAmenaza
                                                select TipAmen.TipoAmenaza);
            if (NombreTipAmen.Count() == 0)
            {
                return "";
            }
            return NombreTipAmen.First();
        }

        //Método que restaura todo el conocimiento dependiente de una lista de Ids de Tipo de Amenazas
        public static void RestauraTipoAmenaza(List<int> LTipoAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Estructuras para recoger los elementos a restaurar
            //Lista de Amenazas por Tipo de Amenaza
            List<int> LAmenazasTipAmenaza = new List<int>();
            //Lista de Relaciones Tipo Activo - Amenaza - Criterio de Riesgo por Amenazas
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorAmenaza = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            List<Matriz_Amenazas_Controles> LRelAmenControlPorAmenaza = new List<Matriz_Amenazas_Controles>();
            List<Matriz_AmenazasVulnerabilidades> LRelAmenVulnPorAmenaza = new List<Matriz_AmenazasVulnerabilidades>();
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstPorRelTipActAmenCrit = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            foreach (int IdTipoAmenaza in LTipoAmenazas)
            {
                TiposAmenazas TipAmenElim = (from TipAmen in agenteBD.TiposAmenazasEstablecer
                                             where TipAmen.IdTipoAmenaza == IdTipoAmenaza
                                             select TipAmen).Single();
                TipAmenElim.Actual = true;
                LAmenazasTipAmenaza = AmenazasFactory.RestauraAmenazasPorTipoAmenaza(IdTipoAmenaza);
            }
            //Recorremos todas las tablas de primer nivel de dependencia con el TipoAmenaza eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Amenazas
            //Nivel 2 de Dependencia
            if (LAmenazasTipAmenaza.Count != 0)
            {
                //Matriz_TipoActivosAmenazasCriterioRiesgo
                LRelTipActAmenCritPorAmenaza = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.RestauraRelacionesPorAmenaza(LAmenazasTipAmenaza);
                //Matriz_Amenazas_Controles
                LRelAmenControlPorAmenaza = Matriz_Amenazas_ControlesFactory.RestauraRelacionesPorAmenaza(LAmenazasTipAmenaza);
                //Matriz Amenazas_Vulnerabilidades
                LRelAmenVulnPorAmenaza = Matriz_AmenazasVulnerabilidadesFactory.RestauraRelacionesPorAmenaza(LAmenazasTipAmenaza);
            }
            //Nivel 3 de Dependencia
            if (LRelTipActAmenCritPorAmenaza.Count() != 0)
            {
                //Instancias Tipo Activo - Amenaza - Criterio de Riesgo
                LInstPorRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.RestauraInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorAmenaza);
            }
            agenteBD.SaveChanges();
        }


        //Método que Restaura una lista de Tipos de Amenazas a través de una lista de sus Ids
        internal static void RestauraTipoAmenazaPorRelaciones(List<int> LIdsTipoAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdTipoAmenaza in LIdsTipoAmenazas)
            {
                //Restauramos la Amenaza
                TiposAmenazas TipAmenRestaurar = (from TipAmen in agenteBD.TiposAmenazasEstablecer
                                                  where TipAmen.IdTipoAmenaza == IdTipoAmenaza
                                                  select TipAmen).Single();
                TipAmenRestaurar.Actual = true;
            }
            agenteBD.SaveChanges();
        }

        //Devuelve el número de tipos de amenazas disponibles en la base de conocimiento
        public static int NumeroTiposAmenazas()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NTipAmen = (from TipAmen in agenteBD.TiposAmenazasEstablecer
                            where TipAmen.Actual == true
                            select TipAmen).Count();
            return NTipAmen;
        }

        //Indica el número de tipos de amenazas deshabilitadas en la base de conocimiento
        public static List<TiposAmenazas> TiposAmenazasEliminadas()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<TiposAmenazas> LTiposAmenazas = new List<TiposAmenazas>();
            IQueryable<TiposAmenazas> TipAmenQuery = (from ta in agenteBD.TiposAmenazasEstablecer
                                                      where ta.Actual == false
                                                      orderby ta.IdTipoAmenaza
                                                      select ta).Distinct();
            if (TipAmenQuery.Count() != 0)
            {
                LTiposAmenazas = TipAmenQuery.ToList();
            }
            return LTiposAmenazas;
        }

        //Método que inserta un tipo de amenaza según su nombre en la base de conocimiento
        public static void InsertarTipoAmenaza(String TipoAmenazaTexto)
        {
            TiposAmenazas TipoAmenazaNueva = new TiposAmenazas();
            TipoAmenazaNueva.TipoAmenaza = TipoAmenazaTexto;
            TipoAmenazaNueva.Actual = true;
            TiposAmenazasFactory.InsertarTipoAmenaza(TipoAmenazaNueva);
        }

        //Método que devuelve un conjunto de tipos de amenazas cuyos nombres contengan la secuencia de TextoBuscar
        public static List<TiposAmenazas> TiposAmenazasEliminadosPorTipoAmenaza(string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<TiposAmenazas> LTiposAmenazas = new List<TiposAmenazas>();
            IQueryable<TiposAmenazas> TipAmenQuery = (from ta in agenteBD.TiposAmenazasEstablecer
                                                      where ta.Actual == false && ta.TipoAmenaza.Contains(TextoBuscar)
                                                      orderby ta.IdTipoAmenaza
                                                      select ta).Distinct();
            if (TipAmenQuery.Count() != 0)
            {
                LTiposAmenazas = TipAmenQuery.ToList();
            }
            return LTiposAmenazas;
        }
    }
}
